package com.block.common.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.block.common.annotate.RedisLock;
import com.block.common.enums.ChargeTypeEnum;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.service.IChannelCommonService;
import com.block.db.entity.ChannelBaseInfo;
import com.block.db.entity.ChannelCountInfo;
import com.block.db.mapper.ChannelBaseInfoMapper;
import com.block.db.mapper.ChannelCountInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@Service
public class ChannelCommonService implements IChannelCommonService {

    private static final String CHANNEL_INFO_KEY_PREFIX = "CHANNEL:INFO:CODE:";
    private static final Long CHANNEL_INFO_KEY_TIME_OUT = 4L;

    @Resource
    ChannelBaseInfoMapper channelBaseInfoMapper;
    @Resource
    ChannelCountInfoMapper channelCountInfoMapper;
    @Autowired
    NotifyExceptionService notifyExceptionService;

    @Resource
    private RedisTemplate<String, ChannelBaseInfo> redisChannelInfoTemplate;

    @Override
    public ChannelBaseInfo getBaseInfoByCode(String channelCode) {
        String redisKey = CHANNEL_INFO_KEY_PREFIX + channelCode;
        ChannelBaseInfo channelInfo = redisChannelInfoTemplate.opsForValue().get(redisKey);
        if (ObjectUtil.isEmpty(channelInfo)) {
            channelInfo = this.channelBaseInfoMapper.getBaseInfoByCode(channelCode);
            if (channelInfo != null) {
                redisChannelInfoTemplate.opsForValue().set(redisKey, channelInfo, CHANNEL_INFO_KEY_TIME_OUT, TimeUnit.HOURS);
            }
        }
        return channelInfo;
    }

    /**
     * 渠道uv数据统计
     *
     * @param countInfoDTO
     */
    @Async
    @Override
    @Transactional
    @RedisLock (lockName = "APPLY::RECORD::ENTER" ,key = "#countInfoDTO.channelCode + ':' + #countInfoDTO.dateInfo",
    expire = 10, timeUnit = TimeUnit.SECONDS)
    public void updateChannelCount(CountInfoDTO countInfoDTO) {
        try {
            ChannelBaseInfo channelBaseInfo = this.getBaseInfoByCode(countInfoDTO.getChannelCode());
            ChannelCountInfo channelCountInfo = channelCountInfoMapper.getEntityByChannelCodeAndDateInfo(countInfoDTO.getChannelCode(), countInfoDTO.getDateInfo());
            if (ObjectUtil.isEmpty(channelCountInfo)) {
                channelCountInfo = new ChannelCountInfo();
                channelCountInfo.setChannelCode(channelBaseInfo.getChannelCode());
                channelCountInfo.setChannelName(channelBaseInfo.getChannelName());
                channelCountInfo.setDateInfo(countInfoDTO.getDateInfo());
                channelCountInfo.setChannelRate(channelBaseInfo.getChannelRate());
                channelCountInfo.setPriceAmount(channelBaseInfo.getPriceAmount());
                channelCountInfo.setOwnerId(String.valueOf(channelBaseInfo.getOwnerId()));
                channelCountInfo.setOwnerName(channelBaseInfo.getOwnerName());
                int insert = channelCountInfoMapper.insert(channelCountInfo);
                if (insert <= 0) {
                    throw new RuntimeException("保存uv统计信息失败：" + JSON.toJSONString(countInfoDTO));
                }
                channelCountInfo = channelCountInfoMapper.getEntityByChannelCodeAndDateInfo(countInfoDTO.getChannelCode(), countInfoDTO.getDateInfo());
            }

            ChannelCountInfo updateEntity = this.getUpdateCountInfo(countInfoDTO, channelCountInfo);
            updateEntity.setId(channelCountInfo.getId());
            channelCountInfoMapper.updateById(updateEntity);
        } catch (Exception exception) {
            exception.printStackTrace();
            notifyExceptionService.notifyNoticeInfo("CHANNEL_COUNT", "渠道统计异常", JSON.toJSONString(countInfoDTO), exception);
        }
    }

    private ChannelCountInfo getUpdateCountInfo(CountInfoDTO countInfoDTO, ChannelCountInfo channelCountInfo) {

        ChannelCountInfo updateEntity = new ChannelCountInfo();

        if (ObjectUtil.isNotEmpty(countInfoDTO.getUvCount())) {
            updateEntity.setUvCount(channelCountInfo.getUvCount() + countInfoDTO.getUvCount());
        }
        if(ObjectUtil.isNotEmpty(countInfoDTO.getPvCount())) {
            updateEntity.setPvCount(channelCountInfo.getPvCount() + countInfoDTO.getPvCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRequestWechatCount())) {
            updateEntity.setWechatRegCount(channelCountInfo.getWechatRegCount() + countInfoDTO.getRequestWechatCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRequestQqCount())) {
            updateEntity.setQqRegCount(channelCountInfo.getQqRegCount() + countInfoDTO.getRequestQqCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getMatchSuccessCount())) {
            int currentSuccessCount = (channelCountInfo.getMatchSuccessCount() != null) ? channelCountInfo.getMatchSuccessCount() : 0;
            updateEntity.setMatchSuccessCount(currentSuccessCount + countInfoDTO.getMatchSuccessCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getMatchSuccessNumber())) {
            int currentSuccessNumber = (channelCountInfo.getMatchSuccessNumber() != null) ? channelCountInfo.getMatchSuccessNumber() : 0;
            updateEntity.setMatchSuccessNumber(currentSuccessNumber + countInfoDTO.getMatchSuccessNumber());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getPushCount())) {
            int currentNumber = (channelCountInfo.getPushCount() != null) ? channelCountInfo.getPushCount() : 0;
            updateEntity.setPushCount(currentNumber + countInfoDTO.getPushCount());
        }


        if (ObjectUtil.isNotEmpty(countInfoDTO.getUvCost())) {
            updateEntity.setUvCost(NumberUtil.add(channelCountInfo.getUvCost(), countInfoDTO.getUvCost()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRegisterCount())) {
            updateEntity.setRegCount(channelCountInfo.getRegCount() + countInfoDTO.getRegisterCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRegisterCountReal())) {
            if (ObjectUtil.equals(ChargeTypeEnum.UNION.getValue(), countInfoDTO.getChargeType())) {
                updateEntity.setRegRealCount(channelCountInfo.getRegRealCount() + countInfoDTO.getRegisterCountReal());
            } else {
                // 注册统计 金额
                updateEntity.setRegRealCount(countInfoDTO.getRegisterCountReal());
            }
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRegisterCost())) {
            if (ObjectUtil.equals(ChargeTypeEnum.UNION.getValue(), countInfoDTO.getChargeType())) {
                updateEntity.setRegCost(NumberUtil.add(channelCountInfo.getRegCost(), countInfoDTO.getRegisterCost()));
            } else {
                // 注册统计 金额
                updateEntity.setRegCost(countInfoDTO.getRegisterCost());
            }
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getLoginCount())) {
            updateEntity.setLoginCount(channelCountInfo.getLoginCount() + countInfoDTO.getLoginCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getAuthCount())) {
            updateEntity.setAuthCount(channelCountInfo.getAuthCount() + countInfoDTO.getAuthCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getFaceCount())) {
            updateEntity.setFaceCount(channelCountInfo.getFaceCount() + countInfoDTO.getFaceCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getSourceCount())) {
            updateEntity.setSourceCount(channelCountInfo.getSourceCount() + countInfoDTO.getSourceCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getSourceFineCount())) {
            updateEntity.setSourceFineCount(channelCountInfo.getSourceFineCount() + countInfoDTO.getSourceFineCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getApprovePushNumber())) {
            updateEntity.setApprovePushNumber(channelCountInfo.getApprovePushNumber() + countInfoDTO.getApprovePushNumber());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getUvProdList())) {
            updateEntity.setUvProdList(channelCountInfo.getUvProdList() + countInfoDTO.getUvProdList());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getProUvCount())) {
            updateEntity.setUvProdCount(channelCountInfo.getUvProdCount() + countInfoDTO.getProUvCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getProUvCountUv())) {
            updateEntity.setUvProdUvCount(channelCountInfo.getUvProdUvCount() + countInfoDTO.getProUvCountUv());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getProUvProfit())) {
            updateEntity.setUvProdProfit(NumberUtil.add(channelCountInfo.getUvProdProfit(), countInfoDTO.getProUvProfit()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getMerchPushCount())) {
            updateEntity.setMerchPushCount(channelCountInfo.getMerchPushCount() + countInfoDTO.getMerchPushCount());
        }
        if (ObjectUtil.isNotEmpty(countInfoDTO.getWuYongCount())) {
            updateEntity.setWuYongCount(channelCountInfo.getWuYongCount() + countInfoDTO.getWuYongCount());
        }
        if (ObjectUtil.isNotEmpty(countInfoDTO.getMerchRealPushCount())) {
            updateEntity.setMerchRealPushCount(channelCountInfo.getMerchRealPushCount() + countInfoDTO.getMerchRealPushCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getMerchPushAmount())) {
            updateEntity.setMerchPushAmount(NumberUtil.add(channelCountInfo.getMerchPushAmount(), countInfoDTO.getMerchPushAmount()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getMerchJiGouPushAmount())) {
            updateEntity.setMerchJiGouPushAmount(NumberUtil.add(channelCountInfo.getMerchJiGouPushAmount(), countInfoDTO.getMerchJiGouPushAmount()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getAppletCount())) {
            updateEntity.setAppletCount(channelCountInfo.getAppletCount() + countInfoDTO.getAppletCount());
        }
        if (ObjectUtil.isNotEmpty(countInfoDTO.getGzhCount())) {
            updateEntity.setGzhCount(channelCountInfo.getGzhCount() + countInfoDTO.getGzhCount());
        }
        if (ObjectUtil.isNotEmpty(countInfoDTO.getErCount())) {
            updateEntity.setErCount(channelCountInfo.getErCount() + countInfoDTO.getErCount());
        }
        if (ObjectUtil.isNotEmpty(countInfoDTO.getComCount())) {
            updateEntity.setComCount(channelCountInfo.getComCount() + countInfoDTO.getComCount());
        }
        if (ObjectUtil.isNotEmpty(countInfoDTO.getWxComCount())) {
            updateEntity.setWxComCount(channelCountInfo.getWxComCount() + countInfoDTO.getWxComCount());
        }

        return updateEntity;
    }
}
